<template>
  <AuModal
    v-model="showUploadPopup"
    :title="t('formulaDetail.import_formula')"
    :padding="false"
    v-bind="$attrs"
    @handleConfirm="submit"
  >
    <div class="flex justify-center py-[30px]">
      <el-upload
        ref="upload"
        v-model:file-list="fileList"
        class="upload-demo"
        :on-change="before"
        multiple
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        :on-exceed="handleExceed"
        :limit="1"
        accept="xlsx,xls"
        :auto-upload="false"
      >
        <el-button type="primary"
          >{{ t("formulaDetail.upload_excel") }}
        </el-button>
        <template #tip>
          <div class="el-upload__tip">
            {{ t("formulaDetail.upload_file_type") }}
            <a
              :href="templateUrl"
              style="color: blue"
              download="配方_模版.xlsx"
              >{{ t("formulaDetail.formula_template") }}</a
            >
          </div>
        </template>
      </el-upload>
    </div>

    <AuModal
      v-model="showError"
      :padding="false"
      width="460px"
      :showCancel="false"
      @handleConfirm="
        () => {
          showError = false;
          errorList = [];
        }
      "
      @close="
        () => {
          errorList = [];
        }
      "
    >
      <template #title>
        <div class="flex items-center text-[14px]">
          <span class="text-[40px] text-[--el-color-danger]">
            <IconifyIconOnline icon="pepicons-pop:exclamation-circle-filled" />
          </span>
          &emsp;{{ t("formulaDetail.error") }}
        </div>
      </template>
      <template #default>
        <el-scrollbar height="50vh">
          <div
            v-for="(item, i) in errorList"
            :key="i"
            class="first:mt-[20px] mt-[10px] px-[20px] last:mb-[10px]"
          >
            <div class="text-[14px] text-[--autata-font-gray-color] mb-[4px]">
              {{ t("formulaDetail.error_reason") }}{{ i + 1 }}
            </div>
            <component :is="item" class="text-[--autata-font-color]]" />
          </div>
        </el-scrollbar>
      </template>
    </AuModal>
  </AuModal>
</template>

<script setup lang="ts">
import { AuModal } from "@/components/AuModal";
import { computed, ref, onMounted, h, getCurrentInstance, PropType } from "vue";
import {
  ElMessage,
  ElMessageBox,
  genFileId,
  UploadRawFile
} from "element-plus";
import ExcelJS from "exceljs"; // 引入exceljs, 用于生成excel文件

import type { UploadProps, UploadUserFile } from "element-plus";
import {
  HxtFormulaDetailList,
  HxtFormulaSpecList,
  addFormulaList,
  updFormula,
  delFormula
} from "@/api/teaInfuser/formula";
import { IconifyIconOnline } from "@/components/ReIcon";
import { useI18n } from "vue-i18n";
import { DEVICE_TYPE_ENUM } from "@/utils/constants";

onMounted(() => {});

const { t } = useI18n();
const { proxy } = getCurrentInstance();
const upload = ref();
const templateUrl = "/admin/配方模板.xlsx";

const hxtFormulaRef = ref([]);
const showError = ref(false);
const errorList = ref([]);
// 查找函数
/* const findObjectByProperty = (propertyName, value) => {
  return groupList.value.find(obj => obj[propertyName] === value);
}; */

const formulaDataList = ref();

const fileList = ref<UploadUserFile[]>([]);
const handlePreview: UploadProps["onPreview"] = uploadFile => {
  //console.log(uploadFile);
};
const handleRemove: UploadProps["onRemove"] = (file, fileLists) => {
  fileList.value = [];
  upload.value?.clearFiles();
  hxtFormulaRef.value = [];
};

const handleExceed: UploadProps["onExceed"] = files => {
  upload.value!.clearFiles();
  const file = files[0] as UploadRawFile;
  file.uid = genFileId();
  upload.value!.handleStart(file);
  hxtFormulaRef.value = [];
};

// const getAllRowsCount = async workbook => {
//   let totalRowsCount = 0;
//
//   // 遍历所有工作表
//   workbook.eachSheet((worksheet, sheetId) => {
//     // 获取工作表的总行数
//     const rowsCount = getRowsCount(worksheet);
//     totalRowsCount += rowsCount;
//   });
//
//   return totalRowsCount;
// };

interface SpecProp {
  waterValue: string;
  temp: string;
  time: string;
  subsectionId: number;
  switchStir: string;
  iceSwitch: string;
  iceWeight: string;
  detail?: {
    begin: string;
    time: string;
  }[];
}

const validate = (
  value: string | number,
  standard: [number, number],
  isPoint = false
) => {
  return new Promise(resolve => {
    const numRegex = isPoint ? /^\d*\.?\d{0,1}$/ : /^-?\d+$/;
    if (!numRegex.test(value as string)) {
      resolve({
        check: false,
        message:
          t("formulaDetail.numberInput") +
          (isPoint ? t("formulaDetail.decimalPoint") : "")
      });
    } else if (Number(value) <= 0 && standard[0] != 0) {
      resolve({ check: false, message: t("formulaDetail.positiveNumber") });
    } else if (Number(value) < standard[0] || Number(value) > standard[1]) {
      resolve({
        check: false,
        message: t("formulaDetail.numberRange", {
          min: standard[0],
          max: standard[1]
        })
      });
    } else {
      resolve({ check: true });
    }
  });
};

const checkSpec = {
  waterValue: (value: string, item: SpecProp) => validate(value, [100, 5000]),
  temp: (value: string, item: SpecProp) => validate(value, [70, 97]),
  time: (value: string, item: SpecProp) => validate(value, [60, 3600]),
  iceWeight: (value: string, item: SpecProp) => {
    console.log(value, item);
    if (item.iceSwitch == "0") {
      return { check: true };
    }
    return validate(value, [0, 3000]);
  },
  timeTeaOut: (value: string, item: SpecProp) => {
    // const val = value ? Number(value) / 1000 : value;
    return validate(value, [0, 60], true);
  }
};

const detailCheck = (
  v: HxtFormulaDetailList,
  detail: {
    begin: string;
    time: string;
  }[]
): Promise<{ check: boolean; message?: string; i?: number }> => {
  return new Promise(resolve => {
    for (let i = 0; i < detail.length; i++) {
      const item = detail[i];
      if (isNaN(parseInt(item.begin)) || isNaN(parseInt(item.time))) {
        resolve({
          check: false,
          message: t("formulaDetail.inputStartTimeAndEndTime"),
          i: i + 1
        });
      }
      if (parseInt(item.begin) < 0 || parseInt(item.time) < 0) {
        resolve({
          check: false,
          message: t("formulaDetail.startTimeAndEndTimeNotLessThanZero"),
          i: i + 1
        });
      }
      if (
        parseInt(item.begin) > parseInt(v.time) ||
        parseInt(item.time) > parseInt(v.time)
      ) {
        resolve({
          check: false,
          message: t("formulaDetail.startTimeAndEndTimeInTeaTime"),
          i: i + 1
        });
      }

      if (i < 1) {
        // if (parseInt(item.begin) >= parseInt(v.time)) {
        //   resolve({
        //     check: false,
        //     message: "请确保开始时间在泡茶时间内",
        //     i: i + 1
        //   });
        // }
      } else {
        if (parseInt(item.time) < parseInt(item.begin)) {
          resolve({
            check: false,
            message: t("formulaDetail.endTimeValidation"),
            i: i + 1
          });
        }
        if (parseInt(detail[i - 1].time) > parseInt(item.begin)) {
          resolve({
            check: false,
            message: t("formulaDetail.previousTimeValidation"),
            i: i + 1
          });
        }
      }
    }
    resolve({ check: true });
  });
};

const check = async (
  hxt: { name: string },
  hxtFormulaSpecDetailList: HxtFormulaSpecList[]
) => {
  const requiredData = {
    waterValue: "进水量(ml)",
    temp: "温度(°C)",
    time: "泡茶时间(S)",
    iceWeight: "冰块重量(g)",
    timeTeaOut: "出茶时间(S)"
  };
  const msgList = [];
  const hxtName = hxt?.name ?? "";
  const message = ({
    v,
    key,
    i,
    errDec
  }: {
    v: HxtFormulaSpecList;
    i: number;
    key: string;
    errDec: string;
  }) => {
    return h("p", { style: "line-height: 2; font-size: 14px" }, [
      h("span", null, t("formulaDetail.formula_name")),
      h("span", null, `${hxtName}，`),
      h("span", null, t("formulaDetail.specification")),
      h("span", null, v.specName),
      h("span", null, t("formulaDetail.in")),
      h("span", null, t("formulaDetail.section") + `${i + 1}`),
      h("span", null, t("formulaDetail.of")),
      h("span", null, key),
      h("span", null, errDec)
    ]);
  };

  if (!hxtName) {
    const msgCheck = {
      check: false,
      message: h("p", { style: "line-height: 2; font-size: 14px" }, [
        h("span", null, t("formulaDetail.formula_name_empty"))
      ])
    };
    msgList.push(msgCheck.message);
  }

  for (const v of hxtFormulaSpecDetailList) {
    if (!v.hxtFormulaDetailList.length) {
      const msg = h("p", { style: "line-height: 2; font-size: 14px" }, [
        h("span", null, t("formulaDetail.formula_name")),
        h("span", null, `${hxtName}，`),
        h("span", null, t("formulaDetail.in")),
        h("span", null, t("formulaDetail.specification")),
        h("span", null, v.specName),
        h("span", null, t("formulaDetail.enter_data"))
      ]);
      // return {
      //   check: false,
      //   message: msg
      // };
      msgList.push(msg);
    }
    for (let i = 0; i < v.hxtFormulaDetailList.length; i++) {
      const spec = v.hxtFormulaDetailList[i];
      for (const key in requiredData) {
        // 检验必填项是否符合rule
        const check = await checkSpec[key](spec[key], spec);
        if (!check.check) {
          const msg = message({
            v,
            i,
            key: requiredData[key],
            errDec: check.message
          });
          msgList.push(msg);
          // return {
          //   check: false,
          //   message: msg
          // };
        }
      }
      // 检查搅拌时间是否出错
      const detail = JSON.parse(spec.detail);
      if (detail.length > 1) {
        const detailCheckRes = await detailCheck(spec, detail);
        if (!detailCheckRes.check) {
          const msg = h("p", { style: "line-height: 2; font-size: 14px" }, [
            h("span", null, t("formulaDetail.formula_name")),
            h("span", null, `${hxtName}, `),
            h("span", null, t("formulaDetail.specification")),
            h("span", null, v.specName),
            h("span", null, t("formulaDetail.in")),
            h("span", null, t("formulaDetail.section") + `${i + 1}`),
            h("span", null, t("formulaDetail.of")),
            h("span", null, t("formulaDetail.stirring_time")),
            h("span", null, t("formulaDetail.section") + `${detailCheckRes.i}`),
            h("span", null, detailCheckRes.message)
          ]);

          msgList.push(msg);
          // return {
          //   check: false,
          //   message: msg
          // };
        }
      }
    }
  }
  // return {
  //   check: true
  // };
  return msgList;
};
/**
 * 根据sheet索引读取Excel文件中的数据
 /**@param file 文件
 /** @param sheetIndex excel文件中sheet表索引 默认是从0开始
 /**@returns  将表中的数据以json形式的数据返回
 */

const before = async (file: any) => {
  const reader = new FileReader();

  reader.onload = async event => {
    const arrayBuffer = event.target?.result as ArrayBuffer;

    const workbook = new ExcelJS.Workbook();
    await workbook.xlsx.load(arrayBuffer);

    const worksheet = workbook.worksheets[0]; // 读取第一个工作表

    //获取配方列表
    const valueArr = worksheet.getRow(2).values as string[]; //根据cell里的值判断导入的配方

    //判断配方个数
    const pfsl = valueArr.filter(item =>
      String(item).includes("*配方名称")
    ).length;
    console.log("配方数：" + pfsl);

    const space = 9;

    for (let i = 0; i < pfsl; i++) {
      // console.log("配方" + i);
      const formulaObject = {}; //配方对象

      //获取配方名称
      let pfmc = worksheet.getRow(2).getCell(2 + i * space).value;

      //配方分类
      let pffl = worksheet.getRow(3).getCell(2 + i * space).value;
      let pftype = null;
      if (pffl === "红茶") {
        pftype = 2;
      } else if (pffl === "绿茶") {
        pftype = 1;
      } else if (!pffl) {
        pftype = 1;
      }

      //获取外部ID
      let wbid = worksheet.getRow(3).getCell(4 + i * space).value;

      //无盖泡茶桶标识
      let wgpct =
        worksheet.getRow(3).getCell(6 + i * space).value == "是" ? 1 : 0;
      // 进水搅拌开关
      const jbInWater =
        worksheet.getRow(3).getCell(8 + i * space).value == "开" ? 1 : 0;

      //获取数据行数，处理规格数量
      let rows = worksheet.actualRowCount; //获取数据行数

      //组织数据
      const hxtFormula = {
        name: pfmc, //配方名称
        type: pftype, //红茶、绿茶
        thirdValue: wbid, //外部id
        switchNoCheck: wgpct, //无盖泡茶桶标识
        jbInWater,
        deviceType: DEVICE_TYPE_ENUM.MAKE_TEA,
        version: props.versionId, //版本
        deleteStatus: 0,
        publishStatus: 1
      };

      const hxtFormulaSpecDetailList = []; //规格集合

      let n = 0; //控制规格起始行数

      let ggNum = 0;
      for (let m = 5; m <= rows; m = 5 + n) {
        //console.log("规格外" + m + n);
        if ("规格名称" == worksheet.getRow(m).getCell(1 + i * space).value) {
          //console.log("规格内" + m + n);
          ggNum++;
          let specName = worksheet.getRow(m).getCell(2 + i * space).value; //规格
          let specId = ggNum;
          let ggwbid = worksheet.getRow(m).getCell(4 + i * space).value; //规格外部ID
          let cyl = worksheet.getRow(m).getCell(6 + i * space).value; //茶叶量

          const hxtFormulaDetailList = []; //分段集合
          let sectionNum = 0; // 超过3个分段
          //处理该规格分段

          for (let j = 0; j <= rows; j++) {
            n++;
            sectionNum++;
            if (
              !String(
                worksheet.getRow(m + j + 2).getCell(1 + i * space).value
              ).includes("段") &&
              worksheet.getRow(m + j + 2).getCell(2 + i * space).value == null
            ) {
              n += 2; //跳往下一个规格
              sectionNum = 0;
              break;
            }
            //
            if (sectionNum > 3) {
              continue;
            }

            let subsectionId = j + 1;
            let waterValue = worksheet
              .getRow(m + j + 2)
              .getCell(2 + i * space).value; //水
            let temp = worksheet.getRow(m + j + 2).getCell(3 + i * space).value; //温度
            let time = worksheet.getRow(m + j + 2).getCell(4 + i * space).value; //时间
            let thirdValue = ggwbid; //外部标志
            let switchStir = 0; //搅拌标志
            let detail = "[]"; //搅拌时间
            if (
              worksheet.getRow(m + j + 2).getCell(5 + i * space).value != null
            ) {
              switchStir = 1;
              let switchTimestr = worksheet
                .getRow(m + j + 2)
                .getCell(5 + i * space).value as string;
              if (switchTimestr) {
                let switchTimeArr = switchTimestr.split(",");
                let switchTimeObjArr = [];
                for (let item of switchTimeArr) {
                  let tempArr = item.split("-");

                  let switchTimeObj = {
                    begin: tempArr[0],
                    time: Number(tempArr[1]) - Number(tempArr[0])
                  };
                  switchTimeObjArr.push(switchTimeObj);
                }
                // console.log(JSON.stringify(switchTimeObjArr));
                detail = JSON.stringify(switchTimeObjArr);
              }
            }

            let iceSwitch = 0; //加冰标志
            let iceWeight = ""; //加冰重量
            if (
              worksheet.getRow(m + j + 2).getCell(6 + i * space).value != null
            ) {
              iceSwitch = 1;
              iceWeight = worksheet.getRow(m + j + 2).getCell(6 + i * space)
                ?.value as string;
            }
            let switchTeaOut = 0;
            let timeTeaOut = "";
            if (
              worksheet.getRow(m + j + 2).getCell(7 + i * space).value != null
            ) {
              switchTeaOut = 1;
              timeTeaOut = worksheet.getRow(m + j + 2).getCell(7 + i * space)
                ?.value as string;
              timeTeaOut = String(Number(timeTeaOut) * 1000);
            }

            //分段
            const hxtFormulaDetail = {
              subsectionId: subsectionId,
              waterValue: waterValue,
              temp: temp,
              time: time,
              thirdValue: thirdValue,
              switchStir: switchStir,
              iceSwitch: iceSwitch,
              iceWeight: iceWeight,
              detail: detail,
              timeTeaOut,
              switchTeaOut
            };

            hxtFormulaDetailList.push(hxtFormulaDetail);
          }
          const hxtFormulaSpecDetail = {
            specName: specName,
            specId: specId,
            thirdValue: ggwbid,
            materialW: cyl,
            hxtFormulaDetailList: hxtFormulaDetailList
          };
          hxtFormulaSpecDetailList.push(hxtFormulaSpecDetail);
        } else {
          //不存在分段
          break;
        }

        console.log("m+n:" + m + n);
      }
      const totalObj = {
        hxtFormula: hxtFormula,
        hxtFormulaSpecDetailList: hxtFormulaSpecDetailList
      };
      hxtFormulaRef.value.push(totalObj);
    }
    ElMessage({
      message: t("formulaDetail.formula_add_success"),
      type: "success"
    });
  };
  await reader.readAsArrayBuffer(file.raw); // 使用 FileReader 读取文件

  return false;
};

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  showModal: {
    type: Boolean,
    default: false
  },
  versionId: {
    type: [Number, String]
  },
  tableData: {
    type: Array as PropType<any[]>,
    default: () => []
  }
});

const emit = defineEmits(["update:modelValue", "handleConfirm"]);

const showUploadPopup = computed({
  get() {
    return props.modelValue;
  },
  set(val: boolean) {
    emit("update:modelValue", val);
  }
});

const uploadTitle = ref("导入配方");

const formRef = ref();

const provinceCity = ref([]);

const submit = async (data: any) => {
  //emit("submit", data);
  console.log(hxtFormulaRef.value);

  if (hxtFormulaRef.value == undefined || hxtFormulaRef.value.length == 0) {
    // ElMessage({
    //   message: "请上传数据文件",
    //   type: "error"
    // });
    proxy.$auMessageBox.confirm(
      t("formulaDetail.upload_file_empty"),
      t("notice.title"),
      {
        type: "error",
        showCancel: false
      }
    );

    upload.value?.clearFiles();
    return false;
  }

  //let service = addFormula;

  let service = addFormulaList;

  /* const hxtFormula = {
    name: "导入测试03", //配方名称
    type: "2", //红茶、绿茶
    thirdValue: "3", //外部id
    switchNoCheck: "1", //1绿茶，2红茶
    deviceType: "泡茶机",
    version: props.versionId, //版本
    deleteStatus: 0,
    publishStatus: 1
  };

  const hxtFormulaSpecDetailList = []; //规格集合

  const hxtFormulaDetailList = []; //分段集合
  //分段
  const hxtFormulaDetail = {
    subsectionId: 1,
    waterValue: 100,
    temp: 70,
    time: 60,
    thirdValue: 123,
    switchStir: 1,
    iceSwitch: 1,
    iceWeight: 2,
    detail: '[{"begin":"1","time":"2"},{"begin":"2","time":"3"}]'
  };

  hxtFormulaDetailList.push(hxtFormulaDetail);

  const hxtFormulaSpecDetail = {
    specName: 1,
    specId: 100,
    hxtFormulaDetailList: hxtFormulaDetailList
  };

  hxtFormulaSpecDetailList.push(hxtFormulaSpecDetail); */
  const errList = [];
  for (let obj of hxtFormulaRef.value) {
    // console.log(obj.hxtFormula);
    const hxtFormula = obj.hxtFormula;
    const hxtFormulaSpecDetailList = obj.hxtFormulaSpecDetailList;

    const checkRes = await check(hxtFormula, hxtFormulaSpecDetailList);
    if (checkRes.length) {
      errList.push(...checkRes);
    }
  }
  if (errList.length > 0) {
    showError.value = true;
    errorList.value = errList;

    upload.value.clearFiles();
    return;
  }
  try {
    let formulaIds = [];
    for (const item of props.tableData) {
      for (const hxt of hxtFormulaRef.value) {
        if (item.name == hxt.hxtFormula.name) {
          formulaIds.push(item.formulaId);
        }
      }
    }
    const res = await service(hxtFormulaRef.value);
    if (res.code == 200) {
      if (formulaIds.length) {
        await delFormula({ formulaIds });
      }
      ElMessage({
        message: t("formulaDetail.formula_add_success"),
        type: "success"
      });

      emit("handleConfirm");
      upload.value.clearFiles();
      hxtFormulaRef.value = [];
      fileList.value = [];
    } else {
      emit("handleConfirm");
      upload.value.clearFiles();
      hxtFormulaRef.value = [];
      fileList.value = [];
      showError.value = true;
      errList.push(h("p", {}, res.message));
      // proxy.$auMessageBox.confirm("导入失败，" + res.message, "失败", {
      //   showCancel: false,
      //   type: "error"
      // });
    }
  } catch (error) {}

  /* if (addList.length > 0) {
    ElMessage({
      message: h("p", {}, [
        h("span", {}, "配方添加成功："),
        h("b", {}, addList.join(","))
      ]),
      type: "success"
    });
  } */
};
</script>
